#include "client.h"
#include "echo.pb.h"
#include "server.h"

#include <brpc/channel.h>
#include <brpc/controller.h>
#include <brpc/server.h>
#include <butil/endpoint.h>
#include <chrono>
#include <cstdio>
#include <cstring>
#include <thread>
using namespace std;

void runClient()
{
    brpc::Channel        channel;
    brpc::ChannelOptions options;
    options.protocol = brpc::PROTOCOL_BAIDU_STD;
    if (channel.Init("127.0.0.1:10086", &options) != 0) {
        LOG(ERROR) << "Fail to initialize channel";
        return;
    }

    example::EchoService_Stub stub(&channel);
    while (!brpc::IsAskedToQuit()) {
        example::EchoRequest  request;
        example::EchoResponse response;
        brpc::Controller      cntl;

        request.set_message("hello world");

        stub.Echo(&cntl, &request, &response, nullptr);
        if (!cntl.Failed()) {
            LOG(INFO) << "Received response: " << response.message();
        } else {
            LOG(ERROR) << "Failed to call Echo: " << cntl.ErrorText();
        }

        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    EchoChannel client;
}

void runServer()
{
    brpc::Server    server;
    EchoServiceImpl service;
    if (server.AddService(&service, brpc::SERVER_DOESNT_OWN_SERVICE) != 0) {
        LOG(ERROR) << "Fail to add service";
        return;
    }

    butil::EndPoint     point(butil::IP_ANY, 10086);
    brpc::ServerOptions options;
    if (server.Start(point, &options) != 0) {
        LOG(ERROR) << "Fail to start server";
        return;
    }
    server.RunUntilAskedToQuit();
}

void printUsage(const char *cmd)
{
    printf("Usgae: %s <command>\n\n", cmd);
    printf("commands: \n");
    printf(" client\n");
    printf(" server\n");
}

int main(int argc, char *argv[])
{
    if (argc < 2) {
        printUsage(argv[0]);
        return 0;
    }

    if (strcmp(argv[1], "client") == 0) {
        runClient();
    } else if (strcmp(argv[1], "server") == 0) {
        runServer();
    } else {
        printUsage(argv[0]);
    }
    return 0;
}